package com.lsz.crm.service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.lsz.crm.base.BaseService;
import com.lsz.crm.mapper.UserMapper;
import com.lsz.crm.mapper.UserRoleMapper;
import com.lsz.crm.model.UserModel;
import com.lsz.crm.pojo.User;
import com.lsz.crm.pojo.UserRole;
import com.lsz.crm.query.UserQuery;
import com.lsz.crm.utils.AssertUtil;
import com.lsz.crm.utils.Md5Util;
import com.lsz.crm.utils.PhoneUtil;
import com.lsz.crm.utils.UserIDBase64;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @Author liushizhong
 * @Date 2021/10/7 21:31
 * @Version 1.0
 */
@Service
public class UserService extends BaseService<User,Integer>{

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private UserRoleMapper userRoleMapper;

    /**
     * 用户登入
     * @param userName
     * @param userPwd
     * @return
     */
    public UserModel userLogin(String userName, String userPwd){
        //1.参数判断，判断用户名密码非空
        checkLoginParams(userName,userPwd);
        //2.根据用户名查询用户
        User user = userMapper.queryUserByUserName(userName);
        //3.判断用户是否为空
        AssertUtil.isTrue(user == null,"用户姓名不存在！");
        //4.判断密码是否正确
        assert user != null;
        checkUserPwd(userPwd,user.getUserPwd());
        //构建返回对象
        return buildUserInfo(user);
    }

    /**
     * 用户修改密码
     * @param
     * @return
     */
     @Transactional(propagation = Propagation.REQUIRED)
     public void updatePassWord(Integer userId,String oldPwd,String newPwd,String repeatPwd){
         //查询用户对象
         User user = userMapper.selectByPrimaryKey(userId);
         //判断用户记录是否存在
         AssertUtil.isTrue(null == user,"用户不存在！");

         //用户参数校验
         checkPassWordParams(user,oldPwd,newPwd,repeatPwd);

         //设置用户新密码
         user.setUserPwd(Md5Util.encode(newPwd));

         // 执行密码更新,判断更新是否成功
         AssertUtil.isTrue(userMapper.updateByPrimaryKeySelective(user) < 1, "用户修改密码失败！");
     }

    /**
     * 判断用户提交修改密码是否合法
     * @param oldPwd
     * @param newPwd
     * @param repeatPwd
     */
    private void checkPassWordParams(User user,String oldPwd, String newPwd, String repeatPwd) {
        // 判断原始密码是否为空
        AssertUtil.isTrue(StringUtils.isBlank(oldPwd),"原始密码不能为空！");
        // 判断密码是否正确
        AssertUtil.isTrue(!user.getUserPwd().equals(Md5Util.encode(oldPwd)),"原始密码不正确！");
        // 判断新密码是否为空
        AssertUtil.isTrue(StringUtils.isBlank(newPwd),"新密码不能为空！");
        // 判断新密码不能与旧密码一致
        AssertUtil.isTrue(oldPwd.equals(newPwd),"新密码不能与原始密码一致！");
        // 判断确认密码是否为空
        AssertUtil.isTrue(StringUtils.isBlank(repeatPwd),"确认密码不能为空！");
        // 判断确认密码是否与原密码一致
        AssertUtil.isTrue(!newPwd.equals(repeatPwd),"输入密码不一致！");
    }

    /**
     * 封装 resultInfo 的 Result 属性
     * @param user
     * @return
     */
    private UserModel buildUserInfo(User user) {
        UserModel userModel  = new UserModel();
        // 加密用户id
        userModel.setUserIdStr(UserIDBase64.encoderUserID(user.getId()));
        userModel.setUserName(user.getUserName());
        userModel.setTrueName(user.getTrueName());
        return userModel;
    }

    /**
     * 密码判断
     * @param pwd
     * @param userPwd
     */
    private void checkUserPwd(String pwd, String userPwd) {
           //将用户穿过来的密码加密
           pwd = Md5Util.encode(pwd);
           //判断密码是否正确
           AssertUtil.isTrue(!userPwd.equals(pwd),"用户密码不正确！");
    }

    /**
     * 参数判断
     * @param userName
     * @param userPwd
     */
    private void checkLoginParams(String userName, String userPwd) {
        //验证用户名
        AssertUtil.isTrue(StringUtils.isBlank(userName),"用户姓名不能为空！");
        //验证用户密码
        AssertUtil.isTrue(StringUtils.isBlank(userPwd),"用户密码不能为空！");
    }

    /**
     * 查询所有销售人员
     * @return
     */
    public List<Map<String,Object>> queryAllSales(){
        return userMapper.queryAllSales();
    }

    /**
     * 分页条件查询用户信息
     * @param userQuery
     * @return
     */
    public Map<String,Object> queryUserByParams(UserQuery userQuery){
        // 返回类型
        Map<String,Object> map = new HashMap<>();
        // 开启分页 参数为：第几页；每页的条数
        PageHelper.startPage(userQuery.getPage(),userQuery.getLimit());
        PageInfo<User> pageInfo = new PageInfo<>(userMapper.selectByParams(userQuery));
        // 返回结果
        map.put("code",0);
        map.put("msg","success");
        // 记录总数
        map.put("count",pageInfo.getTotal());
        // 设置分页好的列表
        map.put("data",pageInfo.getList());
        return map;
    }

    /**
     * 添加用户
     * @param user
     */
    @Transactional(propagation = Propagation.REQUIRED)
    public void addUser(User user){
        // 1. 参数检验
        checkParams(user.getUserName(), user.getEmail(), user.getPhone(), user.getId());
        // 2. 设置默认参数
        user.setIsValid(1);
        user.setCreateDate(new Date());
        user.setUpdateDate(new Date());
        user.setUserPwd(Md5Util.encode("123456"));
        // 3. 执⾏添加，判断结果
        AssertUtil.isTrue(userMapper.insertSelective(user) < 1, "⽤户添加失败!");
        //⽤户⻆⾊分配
        relaionUserRole(user.getId(), user.getRoleIds());

    }

    /**
     * 更新⽤户
     * @param user
     */
    @Transactional(propagation = Propagation.REQUIRED)
    public void updateUser(User user) {
        // 1. 参数校验
        // 通过id查询⽤户对象
        User temp = userMapper.selectByPrimaryKey(user.getId());
        // 判断对象是否存在
        AssertUtil.isTrue(temp == null, "待更新记录不存在！");
        // 验证参数
        checkParams(user.getUserName(),user.getEmail(),user.getPhone(),user.getId());
        // 2. 设置默认参数
        assert temp != null;
        temp.setUpdateDate(new Date());
        // 3. 执⾏更新，判断结果
        AssertUtil.isTrue(userMapper.updateByPrimaryKeySelective(user) < 1, "⽤户更新失败！");
         // ⽤户⻆⾊分配
        relaionUserRole(user.getId(), user.getRoleIds());
    }


    /**
     * 删除⽤户
     * @param ids
     */
    @Transactional(propagation = Propagation.REQUIRED)
    public void deleteUserByIds(Integer[] ids) {
        AssertUtil.isTrue(null==ids || ids.length == 0,"请选择待删除的⽤户记录!");
        AssertUtil.isTrue(userMapper.deleteBatch(ids) != ids.length,"⽤户记录删除失败!");

        for(Integer userId : ids){
            // 通过用户id查询用户角色记录
            int count = userRoleMapper.countUserRoleByUserId(userId);
            if(count > 0){
                // 通过用户id删除用户角色记录
                AssertUtil.isTrue(userRoleMapper.deleteUserRoleByUserId(userId) != count, "⽤户⻆⾊删除失败!");
            }
        }
    }

    /**
     * 用户绑定角色
     * @param userId
     * @param roleIds
     */
    private void relaionUserRole(Integer userId, String roleIds) {
        /**
         * ⽤户⻆⾊分配
         *   原始⻆⾊不存在 添加新的⻆⾊记录
         *   原始⻆⾊存在 添加新的⻆⾊记录
         *   原始⻆⾊存在 清空所有⻆⾊
         *   原始⻆⾊存在 移除部分⻆⾊
         *如何进⾏⻆⾊分配???
         *   如果⽤户原始⻆⾊存在 ⾸先清空原始所有⻆⾊ 添加新的⻆⾊记录到⽤户⻆⾊表
         */

         // 查询用户存在角色
        int count = userRoleMapper.countUserRoleByUserId(userId);
        // 判断角色记录是否存在
        if(count > 0){
            // 删除用户对应的角色
            AssertUtil.isTrue(userRoleMapper.deleteUserRoleByUserId(userId) != count, "⽤户⻆⾊分配失败!");
        }
        // 判断角色id是否存在，存在则添加用户对应的角色记录
        if (StringUtils.isNotBlank(roleIds)){
            // 添加新角色
            List<UserRole> userRoles = new ArrayList<>();
            for(String s : roleIds.split(",")){
                UserRole userRole = new UserRole();
                userRole.setUserId(userId);
                userRole.setRoleId(Integer.parseInt(s));
                userRole.setCreateDate(new Date());
                userRole.setUpdateDate(new Date());
                userRoles.add(userRole);
            }
            // 批量插入用户角色记录
            AssertUtil.isTrue(userRoleMapper.insertBatch(userRoles) < userRoles.size(), "⽤户⻆⾊分配失败!");
        }
    }

    /**
     * 参数检验
     * @param userName
     * @param email
     * @param phone
     * @param id
     */
    private void checkParams(String userName, String email, String phone, Integer id) {
        AssertUtil.isTrue(StringUtils.isBlank(userName), "⽤户名不能为空!");
        // 验证⽤户名是否存在
        User temp = userMapper.queryUserByUserName(userName);
        // 用户存在且与之前的用户不一致
        AssertUtil.isTrue(null != temp && !(temp.getId().equals(id)), " 该⽤户名已存在,请重新输入！");
        AssertUtil.isTrue(StringUtils.isBlank(email), " 邮箱不能为空！");
        AssertUtil.isTrue(StringUtils.isBlank(phone),"手机号码不能为空！");
        AssertUtil.isTrue(!PhoneUtil.isMobile(phone), "⼿机号码格式不正确！");
    }
}
